/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/** *****************************************************************************************************
 *  \file     Ea_Ops.h                                                                                  *
 *  \brief    This file contains interface header for ra ops                                            *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2024/11/14     <td>1.0.0                               *
 * </table>                                                                                             *
 *******************************************************************************************************/

#ifndef EA_OPS_H
#define EA_OPS_H

/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
/* FLS Fls_AddressType & Fls_LengthType USED */
#include "Ea.h"
#include "Ea_Cfg.h"

/********************************************************************************************************
 *                                 Global Macro definition                                              *
 *******************************************************************************************************/

#if defined(EA_DEBUG_ENABLE)
#define EA_ERROR ERROR
#if defined(EA_DEBUG_LOG)
#define EA_DEBUG PRINT
#else
#define EA_DEBUG(...)
#endif /* EA_DEBUG_LOG */
#else
#define EA_ERROR(...)
#define EA_DEBUG(...)
#endif /* EA_DEBUG_ENABLE */

/********************************************************************************************************
 *                                  Global Types definition                                             *
 *******************************************************************************************************/
/* device data end flag type */
typedef uint32 ea_dev_data_end_t;
/* device data end flag definitions */
#define EA_DEV_DATA_END_FLAG                ((ea_dev_data_end_t)0xA5A55A5AU)     /* device data end flag */

struct ea_dev_data_end {
    ea_dev_data_end_t dev_data_end;
    Eep_AddressType end_addr;
    uint16 check_sum;
} __attribute__((aligned(EA_VIRTUAL_PAGE_SIZE)));

/* device info end flag type */
typedef uint32 ea_dev_info_end_t;
/* device data info flag definitions */
#define EA_DEV_DATA_INFO_FLAG               ((ea_dev_info_end_t)0x5A5AA5A5U)     /* device info end flag */

struct ea_dev_info_end {
    ea_dev_info_end_t dev_info_end;
    Eep_AddressType end_addr;
    uint16 check_sum;
} __attribute__((aligned(EA_VIRTUAL_PAGE_SIZE)));

/* device status type */
typedef uint32 ea_dev_status_t;
/* device status definitions */
#define EA_DEV_VALID                        ((ea_dev_status_t)0xA5A5A5A5U)     /* device is valid */

/* device information */
struct ea_dev_info {
    ea_dev_status_t dev_status;
    Eep_AddressType dev_addr;
    Eep_LengthType dev_size;
    uint16 major_version;
    uint16 minor_version;
    uint16 patch_version;
    uint16 check_sum;
} __attribute__((aligned(EA_VIRTUAL_PAGE_SIZE)));

typedef uint32 ea_record_status_t;
typedef uint16 ea_record_number_t; /* block number range is 64K */
typedef uint16 ea_record_length_t; /* block size range is 64K */
typedef Eep_AddressType ea_record_addr_t; /* record addr is eep */

/* block status definitions */
#define EA_RECORD_UNSET                     ((ea_record_status_t)0xF0F0F0F0U)     /* record is empty */
#define EA_RECORD_INVALID                   ((ea_record_status_t)0x5A5A5A5AU)     /* record is marked to invalid */
#define EA_RECORD_VALID                     ((ea_record_status_t)0xA5A5A5A5U)     /* record is marked to valid */
#define EA_BLOCK_INVALID                    ((ea_record_status_t)0x0F0F0F0FU)     /* block is marked to invalid */
#define EA_RECORD_DISCARD                   ((ea_record_status_t)0xAFAF5F5FU)     /* block is marked to discard */

/* record information */
struct ea_record_info {
    ea_record_status_t record_status;
    ea_record_number_t record_num;
    ea_record_length_t record_size;
    ea_record_addr_t record_address;
    uint16 record_crc16;
    uint16 data_crc16;
} __attribute__((aligned(EA_VIRTUAL_PAGE_SIZE)));

union ea_record_info_common {
    struct ea_record_info record_info;
    struct ea_dev_info_end info_end;
} __attribute__((aligned(EA_VIRTUAL_PAGE_SIZE)));

/* block run-time status */
struct ea_block_status {
    uint16 block_number;
    uint16 block_size;
    uint16 dev_index;
    Eep_AddressType block_data_addr;
    Eep_AddressType block_info_addr;
    uint16 record_crc16;
    uint16 data_crc16;
    ea_record_status_t block_status;
};

/* ea device */
struct ea_dev {
    uint16 dev_index;

    Eep_AddressType dev_addr;
    Eep_LengthType dev_size;
    uint16 major_version;
    uint16 minor_version;
    uint16 patch_version;

    Eep_AddressType data_end_addr;
    Eep_AddressType data_info_addr;

    boolean backup_block_active;
    uint16 backup_block_index;
    Eep_AddressType backup_info_addr;
    Eep_AddressType backup_data_addr;
    Eep_LengthType backup_data_size;
};

/* ea fun result */
typedef enum {
    /* The fun has been finished successfully. */
    EA_FUN_OK = 0,
    /* The fun has not been finished successfully. */
    EA_FUN_FAILED = 1,
} Ea_ResultType;

typedef MemIf_JobResultType (*Ea_JobFunctionVoidPtr)(void);
typedef Ea_Internal_JobResultType (*Ea_InternalJobFunctionVoidPtr)(void);

uint16 Ea_GetBlockIndex(uint16 BlockNumber);
MemIf_JobResultType Ea_JobWrite_BackupBlockInfo( void );
MemIf_JobResultType Ea_JobWrite_SyncBlockInfo( void );

/* End of file */
#endif /* EA_OPS_H */
